/**
 * MongoDB数据库连接配置
 */
const { MongoClient, ServerApiVersion } = require('mongodb');
const mongoose = require('mongoose');
const config = require('../config');
const logger = require('../utils/logger');

// MongoDB连接URI
const MONGO_URI = config.mongodb.uri;

/**
 * 建立直接的MongoDB连接（用于原生操作）
 */
const createNativeClient = async () => {
  const client = new MongoClient(MONGO_URI, {
    serverApi: {
      version: ServerApiVersion.v1,
      strict: true,
      deprecationErrors: true,
    }
  });
  
  try {
    await client.connect();
    logger.info("MongoDB原生客户端连接成功");
    
    // 健康检查
    await client.db("admin").command({ ping: 1 });
    logger.info("MongoDB部署健康检查通过");
    
    return client;
  } catch (error) {
    logger.error("MongoDB原生客户端连接失败", { error });
    throw error;
  }
};

/**
 * 使用Mongoose连接MongoDB（用于模型操作）
 */
const connectWithMongoose = async () => {
  try {
    // 使用Mongoose连接
    await mongoose.connect(MONGO_URI, {
      serverApi: {
        version: ServerApiVersion.v1,
        strict: true,
        deprecationErrors: true
      }
    });
    
    logger.info(`Mongoose已连接到MongoDB: ${mongoose.connection.host}`);
    
    // 设置连接事件监听
    mongoose.connection.on('error', (err) => {
      logger.error('Mongoose连接错误', { error: err });
    });
    
    mongoose.connection.on('disconnected', () => {
      logger.warn('Mongoose连接已断开');
    });
    
    // 优雅关闭连接
    process.on('SIGINT', async () => {
      await mongoose.connection.close();
      logger.info('应用终止，Mongoose连接已关闭');
      process.exit(0);
    });
    
    return mongoose.connection;
  } catch (error) {
    logger.error('Mongoose连接MongoDB失败', { error });
    throw error;
  }
};

/**
 * 测试MongoDB连接是否可用
 */
const testConnection = async () => {
  const client = new MongoClient(MONGO_URI, {
    serverApi: {
      version: ServerApiVersion.v1,
      strict: true,
      deprecationErrors: true,
    },
    // 短连接超时设置，仅用于测试
    connectTimeoutMS: 10000,
    socketTimeoutMS: 10000
  });
  
  try {
    await client.connect();
    await client.db("admin").command({ ping: 1 });
    logger.info("MongoDB连接测试成功");
    await client.close();
    return true;
  } catch (error) {
    logger.error("MongoDB连接测试失败", { error: error.message });
    return false;
  }
};

/**
 * 连接数据库
 */
const connectDB = async () => {
  try {
    // 先测试连接
    const isConnectable = await testConnection();
    
    if (!isConnectable) {
      logger.error("MongoDB连接测试失败，尝试使用备用模式运行");
      // 不要抛出错误，而是返回false表示需要使用备用模式
      return false;
    }
    
    // 使用Mongoose连接
    await connectWithMongoose();
    
    return true;
  } catch (error) {
    logger.error("MongoDB连接失败", { error: error.message });
    
    // 不抛出错误，而是返回false让应用程序继续以备用模式运行
    return false;
  }
};

module.exports = {
  connectDB,
  createNativeClient,
  mongoose
}; 